package com.lvkerry.orderfood.config;


import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;


@Configuration
public class OAuth2ServerConfig {

    private static final String RESOURCE_ID = "resource_id";


    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources.resourceId(RESOURCE_ID).stateless(true);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/api/**").authorizeRequests().anyRequest().authenticated();
        }
    }


    @Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
        @Bean
        public TokenStore tokenStore() {
//            return new InMemoryTokenStore();
            return new RedisTokenStore(redisConnectionFactory);
//            return new JdbcTokenStore(dataSource);
        }


        final DataSource dataSource;

        final AuthenticationManager authenticationManager;

        final RedisConnectionFactory redisConnectionFactory;

        final UserDetailsService userDetailsService;

        @Autowired
        public AuthorizationServerConfiguration(AuthenticationManager authenticationManager, RedisConnectionFactory redisConnectionFactory, UserDetailsService userDetailsService, DataSource dataSource) {
            this.authenticationManager = authenticationManager;
            this.redisConnectionFactory = redisConnectionFactory;
            this.userDetailsService = userDetailsService;
            this.dataSource = dataSource;
        }


        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

            clients.jdbc(dataSource);

//            clients.inMemory().withClient("oauth_client_1")
//                    .resourceIds(RESOURCE_ID)
//                    .authorizedGrantTypes("client_credentials", "refresh_token")
//                    .scopes("all")
//                    .authorities("client")
//                    .secret("oauth_client_1_secret_key")
//                    .and().withClient("oauth_client_2")
//                    .resourceIds(RESOURCE_ID)
//                    .authorizedGrantTypes("password", "refresh_token")
//                    .scopes("all")
//                    .authorities("client")
//                    .secret("oauth_client_2_secret_key")
//                    .accessTokenValiditySeconds(86400)
//                    .refreshTokenValiditySeconds(691200);
            //86400 2天
            //691200 8天
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints
                    .tokenStore(tokenStore())
                    .authenticationManager(authenticationManager)
                    .userDetailsService(userDetailsService);
        }

        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            //允许表单认证
            oauthServer.allowFormAuthenticationForClients();
        }

    }

}
